#pragma once

#include <pthread.h>
#include <functional>
#include <cassert>

class thread
{
    // typedef void *(*func)(void *); // 函数类型
    typedef function<void *(void *)> func; // 用于接收任务函数的函数包装器

    static void *handle(void *args)
    {
        // 需要从args中获取this指针，才能访问其他thread的成员
        thread *_this = static_cast<thread *>(args);
        // 执行任务函数
        _this->_task(_this->_args);

        return nullptr;
    }

public:
    // 构造函数
    thread(func task, void *args)
        : _task(task), _args(args)
    {
        int n = pthread_create(&_tid, nullptr, handle, this);
        assert(n == 0); // n必须为，才能创建成功
        (void)n;
    }

    // 析构函数
    ~thread()
    {
        // thread对象销毁前，先将正在运行的线程取消掉
        pthread_cancel(_tid);
    }

    thread(const thread &phd) = delete;            // 删除拷贝构造
    thread &operator=(const thread &phd) = delete; // 删除赋值重载

    void join()
    {
        int n = pthread_join(_tid, nullptr);
        assert(n == 0);
        (void)n;
    }

private:
    pthread_t _tid; // 线程id
    func _task;     // 任务函数,调用时需要传递_args作为参数
    void *_args;    // 任务参数
};
